//==================================================================================================
/*
  EVE - Expressive Vector Engine
  Copyright : EVE Project Contributors
  SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "test.hpp"

#include <eve/module/bessel.hpp>

TTS_CASE_TPL ( "Check eve::cyl_bessel_yn over real,  integral positive orders"
             , eve::test::scalar::ieee_reals
              )
<typename T>(tts::type<T>)
{
  auto constexpr N = 11;
  using a_t  = std::array<T, 8 >;
  using aN_t = std::array<a_t, N >;
  a_t re{ 2.9999999999999982e-01, 1.0000000000000000e+00, 1.7000000000000002e+00, 2.3999999999999995e+00,     3.0999999999999988e+00, 3.7999999999999998e+00, 4.4999999999999991e+00, 5.2000000000000002e+00};
  aN_t resN16;
  //res are taken from octave 9.2.0 bessely outputs
  int p=0;
  resN16[p] = a_t{-8.0727357780451992e-01,8.8256964215676997e-02,4.5202700018163483e-01,5.1041474866574377e-01,3.4310288935449834e-01,6.4503246654993324e-02,-1.9470500862950424e-01,-3.3125093481988449e-01,};
  ++p; //1  1.000e+00
  resN16[p] = a_t{-2.2931051383885306e+00,-7.8121282130028891e-01,-2.8472624506406824e-01,1.0048893833108423e-01,3.4962948226769586e-01,4.1411468930778406e-01,3.0099732306965482e-01,7.9190342982084272e-02,};
  ++p; //2  2.000e+00
  resN16[p] = a_t{-1.4480094011452358e+01,-1.6506826068162548e+00,-7.8699905319818575e-01,-4.2667396672317354e-01,-1.1753548143985584e-01,1.5345185298068242e-01,3.2848159666046195e-01,3.6170875904376304e-01,};
  ++p; //3  3.000e+00
  resN16[p] = a_t{-1.9077481501430970e+02,-5.8215176059647309e+00,-1.5670362330493099e+00,-8.1161221620304036e-01,-5.0128816799654208e-01,-2.5258642301232892e-01,-9.0136815936885713e-03,1.9904716397465649e-01,};
  ++p; //4  4.000e+00
  resN16[p] = a_t{-3.8010162062747440e+03,-3.3278423028972128e+01,-4.7437170634464358e+00,-1.6023565737844276e+00,-8.5269968242441940e-01,-5.5227252089488588e-01,-3.4049983878538009e-01,-1.3203895445762101e-01,};
  ++p; //5  5.000e+00
  resN16[p] = a_t{-1.0116965735231226e+05,-2.6040586662581234e+02,-2.0756338183169209e+01,-4.5295763630783865e+00,-1.6992271414858309e+00,-9.1009256834532526e-01,-5.9631936513587613e-01,-4.0218401698638112e-01,};
  ++p; //6  6.000e+00
  resN16[p] = a_t{-3.3685208955374686e+06,-2.5707802432291510e+03,-1.1735238989637242e+02,-1.7270878272375523e+01,-4.6286781933363272e+00,-1.8427079221191272e+00,-9.8465430596101156e-01,-6.4139184743926558e-01,};
  ++p; //7  7.000e+00
  resN16[p] = a_t{-1.3463966616414651e+08,-3.0588957052123998e+04,-8.0761347285004763e+02,-8.1824814998799255e+01,-1.6218236832719310e+01,-4.9089850804519175e+00,-2.0294254507601552e+00,-1.0779510155657701e+00,};
  ++p; //8  8.000e+00
  resN16[p] = a_t{-6.2798159000979691e+09,-4.2567461848650681e+05,-6.5335820923981355e+03,-4.6004054255395369e+02,-6.8614972018944457e+01,-1.6243026584808984e+01,-5.3291137630705849e+00,-2.2607839636993465e+00,};
  ++p; //9  9.000e+00
  resN16[p] = a_t{-3.3478887500572778e+11,-6.7802049387319852e+06,-6.0684923867367681e+04,-2.9851121353608933e+03,-3.3792355423280060e+02,-6.3482705802954314e+01,-1.6918534595713041e+01,-5.8783073342783716e+00,};
  ++p; //10  1.000e+01
  resN16[p] = a_t{-2.0081052684443582e+13,-1.2161801427868922e+08,-6.3601267062090640e+05,-2.1928300472652754e+04,-1.8935217944940921e+03,-2.8446452721865870e+02,-6.2345024619781604e+01,-1.8087202962648860e+01,};
  using eve::spherical;
  auto h =  eve::half(eve::as<T>());
  for(int j=0; j <= 7; ++j)
  {
    auto c = re[j];
    auto fac = eve::sqrt(eve::pio_2(eve::as(c))*eve::rec(c));
    for(int i=0; i < N; ++i)
    {
      auto res = resN16[i][j];
      TTS_RELATIVE_EQUAL(eve::bessel_y(i, c), res, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_y(-i, c), eve::sign_alternate(i)*res, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_y[spherical](i, c), eve::bessel_y(i+h, c)*fac, tts::prec<T>());
      TTS_RELATIVE_EQUAL(eve::bessel_y[spherical](-i, c), eve::bessel_y(-i+h, c)*fac, tts::prec<T>());
    }
  }
};
